package com.wyl.studyredis.business.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wyl.studyredis.business.entity.Student;
import com.wyl.studyredis.business.mapper.StudentMapper;
import com.wyl.studyredis.business.service.ISchoolService;
import com.wyl.studyredis.business.service.IStudentService;
import com.wyl.studyredis.business.util._CacheKeyUtil;
import com.wyl.studyredis.business.vo.SchoolVo;
import com.wyl.studyredis.business.vo.StudentVo;
import com.wyl.studyredis.framework.util._BeanUtil;
import com.wyl.studyredis.framework.util._SpringContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wyl
 * @since 2022-02-11
 */
@Service("studentService")
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements IStudentService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    @Lazy
    private ISchoolService schoolService;

    @Override
    public StudentVo getStudentVoByIdInCache(String id, boolean isDeep) throws Exception {
        // 1.根据入参id，匹配"student:id"，找到student（走缓存）
        IStudentService _this = _SpringContextUtil.getBean(IStudentService.class);
        Student student = _this.getStudentById(id);
        if(null == student){
            return null;
        }
        StudentVo studentVo = _BeanUtil.copyProperties(student, StudentVo.class);

        // 2.根据schoolId, 匹配"school:schoolId",找到school（走缓存）
        if (isDeep) {
            String schoolId = student.getSchoolId();
            if(StrUtil.isNotBlank(schoolId)){
                SchoolVo schoolVo = schoolService.getSchoolVoByIdInCache(schoolId, false);
                studentVo.setSchoolVo(schoolVo);
            }
        }
        // 3.构造Vo返回值（vo不缓存起来）
        return studentVo;
    }

    @CachePut(cacheNames = Student.cacheName, key = "#result.id")
    @Override
    public Student saveAndCache(Student student) throws Exception {
        // 1.保存student，生成"student:id"
        super.save(student);
        // 2.更新"school:id:student"
        String schoolId = student.getSchoolId();
        if(StrUtil.isNotBlank(schoolId)){
            String schoolStudentKey = _CacheKeyUtil.getSchoolStudentKey(schoolId);
            stringRedisTemplate.opsForList().rightPush(schoolStudentKey, student.getId());
        }
        return student;
    }

    @CachePut(cacheNames = Student.cacheName, key = "#result.id")
    @Override
    public Student updateByIdAndCache(Student student) throws Exception {
        // 1.更新student，更新"student:id"
        super.updateById(student);
        return student;
    }

    @CacheEvict(cacheNames = Student.cacheName, key = "#id")
    @Override
    public void removeByIdAndCache(String id) {
        IStudentService _this = _SpringContextUtil.getBean(IStudentService.class);
        Student student = _this.getStudentById(id);
        // 1.删除student，删除"student:id"
        super.removeById(id);
        // 2.更新"school:id:student"，删除关联关系studentId
        stringRedisTemplate.opsForList().remove(_CacheKeyUtil.getSchoolStudentKey(student.getSchoolId()), 1, id);
    }

    @Cacheable(cacheNames = Student.cacheName, key = "#id", unless = "#result == null")
    @Override
    public Student getStudentById(String id){
        return super.getById(id);
    }

}












